package org.egrit;

import java.awt.Point;

/**
 * Defines basic grid methods.
 * 
 * @author michael
 */
public interface IGrid {
    
    /**
     * Gets the grid width (columns).
     * 
     * @return grid width
     */
    int getWidth();
    
    /**
     * Gets the grid height (rows).
     * 
     * @return grid height
     */
    int getHeight();
    
    /**
     * Gets the bounds of this grid expressed in grid coordinates.
     * 
     * @return grid bounds
     */
    IGridBounds getGridBounds();
    
    /**
     * Tests whether a grid position lies within the bounds of this grid.
     * 
     * @param gridX grid X ordinate
     * @param gridY grid Y ordinate
     * 
     * @return {@code true} if the position lies within the bounds of this grid
     */
    boolean isWithin(int gridX, int gridY);

    /**
     * Gets the outside value that will be returned for queries beyond the
     * grid bounds.
     * 
     * @return the outside value (may be {@code null})
     */
    Number getOutsideValue();

    /**
     * Gets the value for the given grid cell.
     * 
     * @param gridX grid X ordinate
     * @param gridY grid Y ordinate
     * 
     * @return the grid value or outside value if the location is beyond the
     *     grid bounds
     */
    Number getGridValue(int gridX, int gridY);
    
    /**
     * Gets the value for the given grid cell.
     * 
     * @param gridPos grid cell position
     * 
     * @return the grid value or outside value if the location is beyond the
     *     grid bounds
     * 
     * @throws IllegalArgumentException if {@code gridPos} is {@code null}
     */
    Number getGridValue(Point gridPos);
    
    /**
     * Adds a listener to be notified of value changes.
     * 
     * @param listener the listener to add
     */
    void addListener(IGridListener listener);
    
    /**
     * Removes a grid listener.
     * 
     * @param listener the listener to remove
     */
    void removeListener(IGridListener listener);
    
    /**
     * Removes all grid listeners.
     */
    void removeAllListeners();

    /**
     * Acquires the lock (waiting if necessary) to prevent modification of 
     * this grid by other threads.
     */
    void lock();
    
    /**
     * Releases the lock to allow other threads to modify this grid.
     */
    void unlock();

}
